home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
3DDEMO.ZIP
/
3D
/
SOURCE
/
POLYLOW.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-07-16
|
34KB
|
1,466 lines
; Copyright (c) 1996 by Kerrigan Burgess, all rights reserved.
.486
ASSUME CS:_TEXT
ASSUME DS:_DATA
; export Functions
PUBLIC Line
PUBLIC Scan_Convert_Lambert
PUBLIC Scan_Convert_Gouraud
; export Data
PUBLIC _MinClipX
PUBLIC _MaxClipX
PUBLIC _MinClipY
PUBLIC _MaxClipY
PUBLIC _ScreenWidth
PUBLIC _LookPAL
PUBLIC _X1
PUBLIC _X2
PUBLIC _X3
PUBLIC _Y1
PUBLIC _Y2
PUBLIC _Y3
PUBLIC _Z1
PUBLIC _Z2
PUBLIC _Z3
PUBLIC _U1
PUBLIC _V1
PUBLIC _U2
PUBLIC _V2
PUBLIC _U3
PUBLIC _V3
PUBLIC _I1
PUBLIC _I2
PUBLIC _I3
PUBLIC _A1
PUBLIC _A2
PUBLIC _A3
PUBLIC _ColorIndex
PUBLIC _TransLevel
PUBLIC _AvgZ
PUBLIC _RendBuffer
_DATA SEGMENT 'DATA' USE32
; Export data
_MinClipX dd 0
_MaxClipX dd 0
_MinClipY dd 0
_MaxClipY dd 0
_ScreenWidth dd 0
_LookPAL dd 0
_LookPALptr dd 0
_X1 dd 0
_X2 dd 0
_X3 dd 0
_Y1 dd 0
_Y2 dd 0
_Y3 dd 0
_Z1 dd 0
_Z2 dd 0
_Z3 dd 0
_U1 dd 0
_V1 dd 0
_U2 dd 0
_V2 dd 0
_U3 dd 0
_V3 dd 0
_I1 dd 0
_I2 dd 0
_I3 dd 0
_A1 dd 0
_A2 dd 0
_A3 dd 0
_ColorIndex dd 0
_TransLevel dd 0
_AvgZ dd 0
_RendBuffer dd 0
; Locals
_oldx3 dd 0
_oldy3 dd 0
_oldi3 dd 0
_LeftX dd 0
_RightX dd 0
_LeftI dd 0
_RightI dd 0
_MiddleI dd 0
_LeftDx dd 0
_RightDx dd 0
_LeftDi dd 0
_RightDi dd 0
_MiddleDi dd 0
_Width dd 0
_GENERAL dd 0
_color dd 0
_Count dd 0
_Temp dd 0
_DATA ENDS
_TEXT SEGMENT PUBLIC 'CODE' USE32
; ARG Buffer-->edi color-->eax count-->ecx
Line PROC NEAR
mov ah,al
mov ebx,eax
sal ebx,16
or eax,ebx
push ecx
and ecx,0x00000003
rep stosb
pop ecx
sar ecx,2
rep stosd
cld ; Direction bit must be clear on exit.
ret
Line ENDP
Scan_Convert_Lambert PROC NEAR
push ebp
push esi
push edi
mov eax,_X2
cmp eax,_X1
jne @@CheckY_L
cmp eax,_X3
je @@TheEnd_L
@@CheckY_L:
mov eax,_Y2
cmp eax,_Y1
jne @@CheckY2Y1_L
cmp eax,_Y3
je @@TheEnd_L
@@CheckY2Y1_L:
cmp eax,_Y1
jge @@CheckY3Y1_L
mov edx,_X1
mov ecx,_X2
mov _X1,ecx ; _X1=_X2
mov _X2,edx ; _X2=_X1
mov edx,_Y1
mov _Y2,edx ; _Y1=_Y2
mov _Y1,eax ; _Y2=_Y1
@@CheckY3Y1_L:
mov eax,_Y3
cmp eax,_Y1
jge @@CheckY3Y2_L
mov ebx,_X1
mov ecx,_X3
mov _X1,ecx ; _X1=_X3
mov _X3,ebx ; _X3=_X1
mov ebx,_Y1
mov _Y1,eax ; _Y1=_Y3
mov _Y3,ebx ; _Y3=_Y1
@@CheckY3Y2_L:
mov eax,_Y2
cmp eax,_Y3
jle @@Skip1_L
mov ebx,_X2
mov ecx,_X3
mov _X2,ecx ; _X2=_X3
mov _X3,ebx ; _X3=_X2
mov ebx,_Y3
mov _Y3,eax ; _Y3=_Y2
mov _Y2,ebx ; _Y2=_Y3
@@Skip1_L:
mov eax,_Y3
cmp eax,_MinClipY
jl @@TheEnd_L
mov eax,_Y1
cmp eax,_MaxClipY
jg @@TheEnd_L
mov eax,_MinClipX
mov ebx,_MaxClipX
cmp eax,_X1
jle @@CheckXtents_L
cmp eax,_X2
jle @@CheckXtents_L
cmp eax,_X3
jg @@TheEnd_L
@@CheckXtents_L:
cmp ebx,_X1
jge @@TheStart_L
cmp ebx,_X2
jge @@TheStart_L
cmp ebx,_X3
jl @@TheEnd_L
@@TheStart_L: ; now poly is in cliparea
mov _GENERAL,0 ; reset flag
mov edi,_RendBuffer
mov ebx,_LookPAL
mov ecx,_ColorIndex
mov al,BYTE PTR [ ebx + ecx ] ; color=Look_Pal[ _ColorIndex ]
mov ah,al
mov ebx,eax
sal ebx,16
or eax,ebx
mov _color,eax ; replicate color
mov eax,_Y2
cmp eax,_Y1
je @@FLAT_TOP_L
cmp eax,_Y3
je @@FLAT_BOTTOM_L
mov _GENERAL,1 ; GENERAL=TRUE
mov eax,_X3
sub eax,_X1
sal eax,16
mov ebx,_Y3
sub ebx,_Y1
cdq
idiv ebx ; slope = ((_X3-_X1)<<16)/(_Y3-_Y1)
mov ebx,_Y2
sub ebx,_Y1
imul ebx
sar eax,16
add eax,_X1
mov ebx,_X3
mov _oldx3,ebx
mov ebx,_Y3
mov _oldy3,ebx
mov _X3,eax ; _X3=newx
mov ebx,_Y2
mov _Y3,ebx
@@FLAT_BOTTOM_L:
mov eax,_X3
cmp eax,_X2 ; if (_X3<_X2)
jge @@Skip2_L
mov ecx,_X2
mov _X2,eax
mov _X3,ecx
@@Skip2_L:
mov ebx,_Y3
sub ebx,_Y1
mov eax,0x00010000 ; divide by 65536 (fixed point 16).
cdq
idiv ebx
mov ebx,_X2
sub ebx,_X1
mov ecx,eax
imul ebx
mov _LeftDx,eax
mov eax,ecx
mov ebx,_X3
sub ebx,_X1
imul ebx
mov _RightDx,eax
mov ebx,_X1
sal ebx,16
mov _LeftX,ebx
add ebx,0x00008000
mov _RightX,ebx ; RightX=LeftX+32768
mov eax,_MinClipY
cmp eax,_Y1
jle @@Skip3_L
cmp eax,_Y3
jg @@SecondHalf_L ; the whole poly is clipped
sub eax,_Y1
mov ebx,eax
imul _LeftDx
add eax,_LeftX
mov _LeftX,eax
mov eax,ebx
imul _RightDx
add eax,_RightX
mov _RightX,eax
mov eax,_MinClipY
mov _Y1,eax
@@Skip3_L:
mov eax,_MaxClipY
cmp eax,_Y3
jge @@Skip4_L
cmp eax,_Y1 ; the whole poly is clipped
jl @@SecondHalf_L
mov _Y3,eax
@@Skip4_L:
mov eax,_Y1
mov ebx,eax
sal eax,8
sal ebx,6
add eax,ebx
add edi,eax ; Buffer+=(_Y1<<8)+(_Y1<<6)
jmp $+2 ; clear prefetch queue
mov eax,_X1
mov ebx,_MinClipX
mov ecx,_MaxClipX
cmp eax,ebx ; if (_X1>=POLY_MIN_CLIP_X && _X1<=POLY_MAX_CLIP_X && etc.
jl @@Clipped_L
cmp eax,ecx
jg @@Clipped_L
mov eax,_X2
cmp eax,ebx
jl @@Clipped_L
cmp eax,ecx
jg @@Clipped_L
mov eax,_X3
cmp eax,ebx
jl @@Clipped_L
cmp eax,ecx
jg @@Clipped_L
mov ebp,_Y3
sub ebp,_Y1 ; edx holds count
mov ebx,_LeftX
mov edx,_RightX
mov eax,_color
@@DoScanLine_L:
cmp ebp,0
je @@SecondHalf_L
mov esi,ebx
sar esi,16
push edi ; save old place
add edi,esi ; draw scanline
mov ecx,edx
sar ecx,16
sub ecx,esi
inc ecx
push ecx ; save ecx
and ecx,0x00000003
rep stosb
pop ecx
sar ecx,2
rep stosd
add ebx,_LeftDx
add edx,_RightDx
pop edi ; restore old position
add edi,_ScreenWidth
dec ebp
jmp @@DoScanLine_L
@@Clipped_L:
mov eax,_color
mov ebp,_Y3
sub ebp,_Y1
mov ebx,_LeftX
mov edx,_RightX
@@DoScanLineClip_L:
cmp ebp,0
je @@SecondHalf_L
mov esi,ebx
sar esi,16
mov ecx,edx
sar ecx,16
cmp esi,_MinClipX
jge @@Skip5_L
cmp ecx,_MinClipX
jl @@Redo_L
mov esi,_MinClipX
@@Skip5_L:
cmp ecx,_MaxClipX
jle @@Skip6_L
cmp esi,_MaxClipX
jg @@Redo_L
mov ecx,_MaxClipX
@@Skip6_L:
push edi
add edi,esi ; draw scanline
sub ecx,esi
inc ecx
mov esi,ecx ; save ecx
and ecx,0x00000003
rep stosb
mov ecx,esi
sar ecx,2
rep stosd
pop edi ; restore old position
@@Redo_L:
add ebx,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth ; move to next scanline
dec ebp
jmp @@DoScanLineClip_L
@@SecondHalf_L:
cmp _GENERAL,0 ; if not GENERAL Triangle goto end
je @@TheEnd_L
mov eax,_X2 ; setup for bottom half
mov _X1,eax
mov eax,_Y2
mov _Y1,eax
mov eax,_X3
mov _X2,eax
mov eax,_oldx3
mov _X3,eax
mov eax,_oldy3
mov _Y3,eax
mov edi,_RendBuffer
@@FLAT_TOP_L:
mov eax,_X2
cmp eax,_X1
jge @@Skip7_L
mov ebx,_X1
mov _X2,ebx
mov _X1,eax
@@Skip7_L:
mov ebx,_Y3
sub ebx,_Y1
mov eax,0x00010000 ; eax=65536
cdq
idiv ebx
mov ebx,eax ; save height
mov ecx,_X3
sub ecx,_X1
imul ecx
mov _LeftDx,eax
mov eax,ebx ; restore eax
mov ecx,_X3
sub ecx,_X2
imul ecx
mov _RightDx,eax
mov eax,_X1
sal eax,16
mov _LeftX,eax
mov eax,_X2
sal eax,16
add eax,0x00008000 ; add 0.5 to it
mov _RightX,eax
mov eax,_MinClipY
cmp eax,_Y1
jle @@Skip8_L
cmp eax,_Y3
jg @@TheEnd_L ; poly is totally clipped
sub eax,_Y1
mov ecx,eax
imul _LeftDx
add eax,_LeftX
mov _LeftX,eax
mov eax,ecx
imul _RightDx
add eax,_RightX
mov _RightX,eax
mov ebx,_MinClipY
mov _Y1,ebx ; _Y1=POLY_MIN_CLIP_Y
@@Skip8_L:
mov eax,_MaxClipY
cmp eax,_Y3
jge @@Skip9_L
cmp eax,_Y1
jl @@TheEnd_L
mov _Y3,eax
@@Skip9_L:
mov eax,_Y1
mov ebx,eax
sal eax,8
sal ebx,6
add eax,ebx
add edi,eax ; Buffer+=(_Y1<<8)+(_Y1<<6)
jmp $+2 ; clear prefetch queue
mov eax,_X1
mov ebx,_MinClipX
mov ecx,_MaxClipX
cmp eax,ebx ; if (_X1>=POLY_MIN_CLIP_X && _X1<=POLY_MAX_CLIP_X && etc.
jl @@Clipped2_L
cmp eax,ecx
jg @@Clipped2_L
mov eax,_X2
cmp eax,ebx
jl @@Clipped2_L
cmp eax,ecx
jg @@Clipped2_L
mov eax,_X3
cmp eax,ebx
jl @@Clipped2_L
cmp eax,ecx
jg @@Clipped2_L
mov ebp,_Y3 ; Draw regular poly (no clip)
sub ebp,_Y1 ; edx holds count
mov ebx,_LeftX
mov edx,_RightX
mov eax,_color
@@DoScanLine2_L:
cmp ebp,0
je @@TheEnd_L
mov esi,ebx
sar esi,16
push edi ; save old position
add edi,esi
mov ecx,edx
sar ecx,16
sub ecx,esi
inc ecx
push ecx ; save ecx
and ecx,0x00000003
rep stosb
pop ecx
sar ecx,2
rep stosd
add ebx,_LeftDx
add edx,_RightDx
pop edi ; restore old position
add edi,_ScreenWidth
dec ebp
jmp @@DoScanLine2_L
@@Clipped2_L:
mov eax,_color
mov ebp,_Y3
sub ebp,_Y1
mov ebx,_LeftX
mov edx,_RightX
@@DoScanLineClip2_L:
cmp ebp,0
je @@TheEnd_L
mov esi,ebx
sar esi,16
mov ecx,edx
sar ecx,16
cmp esi,_MinClipX
jge @@Skip10_L
cmp ecx,_MinClipX
jl @@Redo2_L
mov esi,_MinClipX
@@Skip10_L:
cmp ecx,_MaxClipX
jle @@Skip11_L
cmp esi,_MaxClipX
jg @@Redo2_L
mov ecx,_MaxClipX
@@Skip11_L:
push edi ; save old position
add edi,esi
sub ecx,esi
inc ecx
mov esi,ecx ; save ecx
and ecx,0x00000003
rep stosb
mov ecx,esi
sar ecx,2
rep stosd
pop edi ; restore saved position
@@Redo2_L:
add ebx,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
dec ebp
jmp @@DoScanLineClip2_L
@@TheEnd_L:
pop edi
pop esi
pop ebp
cld
ret
Scan_Convert_Lambert ENDP
Scan_Convert_Gouraud PROC NEAR
push ebp
push esi
push edi
mov eax,_X2
cmp eax,_X1
jne @@CheckY_G
cmp eax,_X3
je @@TheEnd_G
@@CheckY_G:
mov eax,_Y2
cmp eax,_Y1
jne @@CheckY2Y1_G
cmp eax,_Y3
je @@TheEnd_G
@@CheckY2Y1_G:
cmp eax,_Y1
jge @@CheckY3Y1_G
mov edx,_X1
mov ecx,_X2
mov _X1,ecx ; _X1=_X2
mov _X2,edx ; _X2=_X1
mov edx,_Y1
mov _Y2,edx ; _Y1=_Y2
mov _Y1,eax ; _Y2=_Y1
mov eax,_I1
mov ebx,_I2
mov _I2,eax ; _I2=_I1
mov _I1,ebx ; _I1=_I2
@@CheckY3Y1_G:
mov eax,_Y3
cmp eax,_Y1
jge @@CheckY3Y2_G
mov ebx,_X1
mov ecx,_X3
mov _X1,ecx ; _X1=_X3
mov _X3,ebx ; _X3=_X1
mov ebx,_Y1
mov _Y1,eax ; _Y1=_Y3
mov _Y3,ebx ; _Y3=_Y1
mov eax,_I1
mov ebx,_I3
mov _I3,eax ; _I3=_I1
mov _I1,ebx ; _I1=_I3
@@CheckY3Y2_G:
mov eax,_Y2
cmp eax,_Y3
jle @@Skip1_G
mov ebx,_X2
mov ecx,_X3
mov _X2,ecx ; _X2=_X3
mov _X3,ebx ; _X3=_X2
mov ebx,_Y3
mov _Y3,eax ; _Y3=_Y2
mov _Y2,ebx ; _Y2=_Y3
mov eax,_I2
mov ebx,_I3
mov _I2,ebx ; _I2=_I3
mov _I3,eax ; _I3=_I2
@@Skip1_G:
mov eax,_Y3
cmp eax,_MinClipY
jl @@TheEnd_G
mov eax,_Y1
cmp eax,_MaxClipY
jg @@TheEnd_G
mov eax,_MinClipX
mov ebx,_MaxClipX
cmp eax,_X1
jle @@CheckXtents_G
cmp eax,_X2
jle @@CheckXtents_G
cmp eax,_X3
jg @@TheEnd_G
@@CheckXtents_G:
cmp ebx,_X1
jge @@TheStart_G
cmp ebx,_X2
jge @@TheStart_G
cmp ebx,_X3
jl @@TheEnd_G
@@TheStart_G: ; now poly is in cliparea
mov _GENERAL,0 ; reset flag
mov edi,_RendBuffer
mov esi,_LookPAL
add esi,_ColorIndex ; LookPAL[ _ColorIndex + (MiddleI>>16) ]
mov eax,_Y2
cmp eax,_Y1
je @@FLAT_TOP_G
cmp eax,_Y3
je @@FLAT_BOTTOM_G
mov _GENERAL,1 ; GENERAL=TRUE
mov eax,0x00010000 ; 65536
cdq
mov ebx,_Y3
sub ebx,_Y1
div ebx
mov ebp,eax ; save height
mov ebx,_x3
sub ebx,_x1
imul ebx
mov ebx,_Y2
sub ebx,_Y1
imul ebx
sar eax,16
add eax,_X1 ; newx
mov ebx,_X3
mov _oldx3,ebx
mov ebx,_Y3
mov _oldy3,ebx
mov ebx,_I3
mov _oldi3,ebx
mov _X3,eax ; _X3=newx
mov eax,_Y2
sub eax,_Y1
imul _I3
mov ebx,eax
mov eax,_Y3
sub eax,_Y2
imul _I1
add eax,ebx
imul ebp ; multiply by height
sar eax,16 ; holds newi
mov _I3,eax ; _I3=newi
mov ebx,_Y2 ; _Y3=_Y2
mov _Y3,ebx
@@FLAT_BOTTOM_G:
mov eax,_X3
cmp eax,_X2 ; if (_X3<_X2)
jge @@Skip2_G
mov ecx,_X2
mov _X2,eax
mov _X3,ecx
mov eax,_I3
mov ebx,_I2
mov _I3,ebx
mov _I2,eax
@@Skip2_G:
mov ebx,_Y2
sub ebx,_Y1
mov eax,0x00010000 ; divide by 65536 (fixed point 16).
cdq
idiv ebx
mov ecx,eax ; save height
mov eax,_X2
sub eax,_X1
imul ecx
mov _LeftDx,eax
mov eax,_X3
sub eax,_X1
imul ecx
mov _RightDx,eax
mov ebx,_X1
sal ebx,16
mov _LeftX,ebx
add ebx,0x00008000
mov _RightX,ebx ; RightX=LeftX+32768
mov eax,_I1
sal eax,16
mov _LeftI,eax
mov _RightI,eax
mov eax,_I2
sub eax,_I1
imul ecx
mov _leftDi,eax
mov eax,_I3
sub eax,_I1
imul ecx
mov _RightDi,eax
mov _MiddleDi,0
mov eax,_MinClipY ; if (_Y1 < POLY_MIN_CLIP_Y)
cmp eax,_Y1
jle @@Skip3_G
cmp eax,_Y3
jg @@SecondHalf_G ; the whole poly is clipped
sub eax,_Y1
mov ebx,eax ; save ydiff
imul _LeftDx
add _LeftX,eax
mov eax,ebx
imul _RightDx
add _RightX,eax
mov eax,ebx
imul _LeftDi
add _LeftI,eax
mov eax,ebx
imul _RightDi
add _RightI,eax
mov eax,_RightI
sub eax,_LeftI
cdq
mov ebx,_RightX
sub ebx,_LeftX
sar ebx,16 ; get whole number
inc ebx ; to avoid divide by 0
idiv ebx
mov _MiddleDi,eax
mov eax,_MinClipY
mov _Y1,eax
@@Skip3_G:
mov eax,_MaxClipY
cmp eax,_Y3
jge @@Skip4_G
cmp eax,_Y1 ; the whole poly is clipped
jl @@TheEnd_G
mov _Y3,eax
@@Skip4_G:
mov eax,_Y1 ; optimized for 320x200
mov ebx,eax
sal eax,8
sal ebx,6
add eax,ebx
add edi,eax ; Buffer+=(_Y1<<8)+(_Y1<<6)
jmp $+2 ; clear prefetch queue
mov eax,_X1
mov ebx,_MinClipX
mov ecx,_MaxClipX
cmp eax,ebx ; if (_X1>=POLY_MIN_CLIP_X && _X1<=POLY_MAX_CLIP_X && etc.
jl @@Clipped_G
cmp eax,ecx
jg @@Clipped_G
mov eax,_X2
cmp eax,ebx
jl @@Clipped_G
cmp eax,ecx
jg @@Clipped_G
mov eax,_X3
cmp eax,ebx
jl @@Clipped_G
cmp eax,ecx
jg @@Clipped_G
mov ebp,_Y3
sub ebp,_Y1 ; count
mov _Count,ebp
mov eax,_LeftX
mov edx,_RightX
mov ebx,_LeftI
mov ecx,_RightI
push eax ; need regs ( Crappy Intel )
push edx
push edi ; save old place
shr eax,16
add edi,eax ; mov to required point
shr edx,16
sub edx,eax
inc edx
mov ebp,edx
mov eax,edi ; read in edi into active cache
mov eax,_LeftI ; start at left end
@@DoScanLine_G:
cmp _Count,0
je @@Cleanup_G
@@DoInnerScanLine_G:
cmp ebp,0 ; inner for loop
je @@DoUpdateData_G
mov edx,eax ; get MiddleI
sar edx,16 ; get whole part
mov dl,BYTE PTR [ esi+edx ]
mov [edi],dl
inc edi
add eax,_MiddleDi;
dec ebp
jmp @@DoInnerScanLine_G
@@DoUpdateData_G:
add ebx,_LeftDi
add ecx,_RightDi
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi ; save old place
shr eax,16 ; get whole part
add edi,eax ; move buffer into postion
shr edx,16
sub edx,eax
inc edx
mov ebp,edx ; holds horiz count
mov eax,ecx
sub eax,ebx
cdq
idiv ebp
mov _MiddleDi,eax
mov eax,ebx ; Start MiddleI from LeftI
mov edx,edi ; get buffer in active cache
dec _Count
jmp @@DoScanLine_G
@@Clipped_G:
mov ebp,_Y3
sub ebp,_Y1
mov _Count,ebp
mov eax,_LeftX
mov edx,_RightX
mov ebx,_LeftI
mov _MiddleI,ebx ; start MiddleI at LeftI
mov ecx,_RightI
push eax
push edx
push edi ; save old place
@@DoScanLineClip_G:
cmp _Count,0
je @@Cleanup_G
sar eax,16 ; ClipLeftX
sar edx,16 ; ClipRightX
cmp eax,_MinClipX
jge @@Skip6_G
cmp edx,_MinClipX
jge @@Skip5_G
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi
add ebx,_LeftDi
add ecx,_RightDi
dec _Count
jmp @@DoScanLineClip_G
@@Skip5_G:
mov ebp,edx ; will be obliterated by imul
sub eax,_MinClipX
neg eax
imul _MiddleDi
add eax,ebx ; Add LeftI
mov _MiddleI,eax
mov eax,_MinClipX
mov edx,ebp ; restore ClipRightX
@@Skip6_G:
cmp edx,_MaxClipX
jle @@Skip8_G
cmp eax,_MaxClipX
jle @@Skip7_G
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi
add ebx,_LeftDi
add ecx,_RightDi
dec _Count
jmp @@DoScanLineClip_G
@@Skip7_G:
mov edx,_MaxClipX
@@Skip8_G:
add edi,eax ; mov to required point
sub edx,eax
inc edx
mov ebp,edx ; horiz count
mov eax,edi ; read in edi into active cache
mov eax,_MiddleI
@@DoInnerScanLineClip_G:
cmp ebp,0 ; inner for loop
je @@DoUpdateDataClip_G
mov edx,eax ; get MiddleI
sar edx,16 ; get whole part
mov dl,BYTE PTR [ esi+edx ]
mov [edi],dl
inc edi
add eax,_MiddleDi;
dec ebp
jmp @@DoInnerScanLineClip_G
@@DoUpdateDataClip_G:
add ebx,_LeftDi
add ecx,_RightDi
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi ; save old place
mov ebp,eax
mov _Temp,edx
sub edx,eax
sar edx,16
inc edx
mov _Width,edx
mov eax,ecx
sub eax,ebx
cdq
idiv _Width
mov _MiddleDi,eax
mov _MiddleI,ebx ; Start MiddleI from LeftI
mov eax,ebp ; restore LeftX, RightX
mov edx,_Temp
dec _Count
jmp @@DoScanLineClip_G
@@Cleanup_G:
pop edi
pop edx
pop eax
@@SecondHalf_G:
cmp _GENERAL,0 ; if not GENERAL Triangle goto end
je @@TheEnd_G
mov eax,_X2 ; setup for bottom half
mov _X1,eax
mov eax,_Y2
mov _Y1,eax
mov eax,_I2
mov _I1,eax
mov eax,_X3
mov _X2,eax
mov eax,_I3
mov _I2,eax
mov eax,_oldx3
mov _X3,eax
mov eax,_oldy3
mov _Y3,eax
mov eax,_oldi3
mov _I3,eax
mov edi,_RendBuffer
@@FLAT_TOP_G:
mov eax,_X2
cmp eax,_X1
jge @@Skip9_G
mov ebx,_X1
mov _X2,ebx
mov _X1,eax
mov eax,_I2
mov ebx,_I1
mov _I2,ebx
mov _I1,eax
@@Skip9_G:
mov ebx,_Y3
sub ebx,_Y1
mov eax,0x00010000 ; eax=65536
cdq
idiv ebx
mov ebx,eax ; save height
mov eax,_X3
sub eax,_X1
imul ebx
mov _LeftDx,eax
mov eax,_X3
sub eax,_X2
imul ebx
mov _RightDx,eax
mov eax,_X1
sal eax,16
mov _LeftX,eax
mov eax,_X2
sal eax,16
add eax,0x00008000 ; add 0.5 to it
mov _RightX,eax
mov eax,_I1
sal eax,16
mov _LeftI,eax
mov eax,_I2
sal eax,16
mov _RightI,eax
mov eax,_I3
sub eax,_I1
imul ebx ; multiply times height
mov _LeftDi,eax
mov eax,_I3
sub eax,_I2
imul ebx
mov _RightDi,eax
mov eax,_RightI
sub eax,_LeftI
cdq
mov ebx,_RightX
sub ebx,_LeftX
sar ebx,16
inc ebx
idiv ebx
mov _MiddleDi,eax
mov ebx,_MinClipY
cmp ebx,_Y1
jle @@Skip10_G
cmp ebx,_Y3
jg @@TheEnd_G ; poly is totally clipped
sub ebx,_Y1 ; ydiff
mov eax,ebx
imul _LeftDx
add _LeftX,eax
mov eax,ebx
imul _RightDx
add _RightX,eax
mov eax,ebx
imul _LeftDi
add _LeftI,eax
mov eax,ebx
imul _RightDi
add _RightI,eax
mov eax,_RightI
sub eax,_LeftI
cdq
mov ebx,_RightX
sub ebx,_LeftX
sar ebx,16
inc ebx
idiv ebx
mov _MiddleDi,eax
mov ebx,_MinClipY
mov _Y1,ebx ; _Y1=POLY_MIN_CLIP_Y
@@Skip10_G:
mov eax,_MaxClipY
cmp eax,_Y3
jge @@Skip11_G
cmp eax,_Y1
jl @@TheEnd_G
mov _Y3,eax
@@Skip11_G:
mov eax,_Y1
mov ebx,eax
sal eax,8
sal ebx,6
add eax,ebx
add edi,eax ; Buffer+=(_Y1<<8)+(_Y1<<6)
jmp $+2 ; clear prefetch queue
mov eax,_X1
mov ebx,_MinClipX
mov ecx,_MaxClipX
cmp eax,ebx ; if (_X1>=POLY_MIN_CLIP_X && _X1<=POLY_MAX_CLIP_X && etc.
jl @@Clipped2_G
cmp eax,ecx
jg @@Clipped2_G
mov eax,_X2
cmp eax,ebx
jl @@Clipped2_G
cmp eax,ecx
jg @@Clipped2_G
mov eax,_X3
cmp eax,ebx
jl @@Clipped2_G
cmp eax,ecx
jg @@Clipped2_G
mov ebp,_Y3
sub ebp,_Y1 ; count
mov _Count,ebp
mov eax,_LeftX
mov edx,_RightX
mov ebx,_LeftI
mov ecx,_RightI
push eax
push edx
push edi ; save old place
shr eax,16
add edi,eax ; mov to required point
shr edx,16
sub edx,eax
inc edx
mov ebp,edx
mov eax,edi ; read in edi into active cache
mov eax,_LeftI ; start at left end
@@DoScanLine2_G:
cmp _Count,0
je @@Cleanup2_G
@@DoInnerScanLine2_G:
cmp ebp,0 ; inner for loop
je @@DoUpdateData2_G
mov edx,eax ; get MiddleI
sar edx,16 ; get whole part
mov dl,BYTE PTR [ esi+edx ]
mov [edi],dl
inc edi
add eax,_MiddleDi;
dec ebp
jmp @@DoInnerScanLine2_G
@@DoUpdateData2_G:
add ebx,_LeftDi
add ecx,_RightDi
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi ; save old place
shr eax,16 ; get whole part
add edi,eax ; move buffer into postion
shr edx,16
sub edx,eax
inc edx
mov ebp,edx ; holds horiz count
mov eax,ecx
sub eax,ebx
cdq
idiv ebp
mov _MiddleDi,eax
mov eax,ebx ; Start MiddleI from LeftI
mov edx,edi ; get buffer in active cache
dec _Count
jmp @@DoScanLine2_G
@@Clipped2_G:
mov ebp,_Y3
sub ebp,_Y1
mov _Count,ebp
mov eax,_LeftX
mov edx,_RightX
mov ebx,_LeftI
mov _MiddleI,ebx ; start MiddleI at LeftI
mov ecx,_RightI
push eax
push edx
push edi ; save old place
@@DoScanLineClip2_G:
cmp _Count,0
je @@Cleanup2_G
sar eax,16 ; ClipLeftX
sar edx,16 ; ClipRightX
cmp eax,_MinClipX
jge @@Skip13_G
cmp edx,_MinClipX
jge @@Skip12_G
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi
add ebx,_LeftDi
add ecx,_RightDi
dec _Count
jmp @@DoScanLineClip2_G
@@Skip12_G:
mov ebp,edx ; save edx
sub eax,_MinClipX
neg eax
imul _MiddleDi
add eax,ebx ; Add LeftI
mov _MiddleI,eax
mov eax,_MinClipX
mov edx,ebp
@@Skip13_G:
cmp edx,_MaxClipX
jle @@Skip15_G
cmp eax,_MaxClipX
jle @@Skip14_G
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi
add ebx,_LeftDi
add ecx,_RightDi
dec _Count
jmp @@DoScanLineClip2_G
@@Skip14_G:
mov edx,_MaxClipX
@@Skip15_G:
add edi,eax ; mov to required point
sub edx,eax
inc edx
mov ebp,edx ; horiz count
mov eax,edi ; read in edi into active cache
mov eax,_MiddleI
@@DoInnerScanLineClip2_G:
cmp ebp,0 ; inner for loop
je @@DoUpdateDataClip2_G
mov edx,eax ; get MiddleI
sar edx,16 ; get whole part
mov dl,BYTE PTR [ esi+edx ]
mov [edi],dl
inc edi
add eax,_MiddleDi;
dec ebp
jmp @@DoInnerScanLineClip2_G
@@DoUpdateDataClip2_G:
add ebx,_LeftDi
add ecx,_RightDi
pop edi
pop edx
pop eax
add eax,_LeftDx
add edx,_RightDx
add edi,_ScreenWidth
push eax
push edx
push edi ; save old place
mov ebp,eax
mov _Temp,edx
sub edx,eax
sar edx,16
inc edx
mov _Width,edx
mov eax,ecx
sub eax,ebx
cdq
idiv _Width
mov _MiddleDi,eax
mov _MiddleI,ebx ; Start MiddleI from LeftI
mov eax,ebp ; restore LeftX, RightX
mov edx,_Temp
dec _Count
jmp @@DoScanLineClip2_G
@@Cleanup2_G:
pop edi ; pop regs that have been previously pushed.
pop edx
pop eax
@@TheEnd_G:
pop edi
pop esi
pop ebp
cld
ret
Scan_Convert_Gouraud ENDP
_TEXT ENDS
END